package com.mybatis.jpa.executor;

import com.mybatis.jpa.sqlbuilder.SqlBuilder;
import org.apache.ibatis.builder.SqlSourceBuilder;
import org.apache.ibatis.mapping.ParameterMapping;
import org.apache.ibatis.mapping.SqlSource;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.session.Configuration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;

public abstract class Executor {

    private static final Logger logger = LoggerFactory.getLogger( Executor.class);

	private SqlBuilder sqlBuilder;
	
	public abstract void process(MetaObject metaStatementHandler) throws Exception;

    public void setSqlBuilder(SqlBuilder sqlBuilder) {
        this.sqlBuilder = sqlBuilder;
    }

    public void genSql(MetaObject metaStatementHandler) throws Exception {
        String newSql = sqlBuilder.buildSql(metaStatementHandler);
        logger.debug("Auto generated sql:{}", newSql);

        setSql(newSql, metaStatementHandler);
    }

    /**
     * 生成的sql替换原来BoundSql对象的sql和parameterMappings属性的值
     * @param sql
     * @param metaStatementHandler
     */
    private void setSql(String sql, MetaObject metaStatementHandler) {
        Configuration configuration = (Configuration) metaStatementHandler.getValue("delegate.configuration");
        //获取入库数据
        Object parameterObject = metaStatementHandler.getValue("delegate.boundSql.parameterObject");
        SqlSourceBuilder builder = new SqlSourceBuilder(configuration);
        SqlSource sqlSource = builder.parse(sql, parameterObject.getClass(), null);
        List<ParameterMapping> parameterMappings = sqlSource.getBoundSql(parameterObject).getParameterMappings();
        // StatementHandler.BoundSql对象属性赋值
        metaStatementHandler.setValue("delegate.boundSql.sql", sqlSource.getBoundSql(parameterObject).getSql());
        metaStatementHandler.setValue("delegate.boundSql.parameterMappings", parameterMappings);
    }
}
